package cn.starrysky108.simpleerp.pub.service.impl;

import cn.starrysky108.simpleerp.core.constant.Constants;
import cn.starrysky108.simpleerp.pub.response.EnumListResponse;
import cn.starrysky108.simpleerp.pub.service.EnumService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Carl Lee
 */
@Service
@Slf4j
public class EnumServiceImpl implements EnumService {
    /**
     * 获取枚举的所有值
     *
     * @return list
     */
    @Override
    public <T> List<EnumListResponse> getEnumList(Class<T> clazz) {
        ArrayList<EnumListResponse> list = new ArrayList<>();
        Method codeMethod;
        Method descriptionMethod;
        try {
            Object[] objects = clazz.getEnumConstants();
            codeMethod = clazz.getMethod("getCode");
            descriptionMethod = clazz.getMethod("getDescription");
            for (Object obj : objects) {
                int code = Integer.parseInt(codeMethod.invoke(obj).toString());
                String description = descriptionMethod.invoke(obj).toString();
                EnumListResponse enumListResponse = new EnumListResponse();
                enumListResponse.setCode(code);
                enumListResponse.setDescription(description);
                list.add(enumListResponse);
            }
        } catch (Exception e) {
            return null;
        }
        return list;
    }


    /**
     * 获取所有Enum
     */
    @Override
    public Map<String, List<EnumListResponse>> listAll() {
        Map<String, List<EnumListResponse>> handlerMap = new HashMap<>(3);
        String pattern = ClassUtils.convertClassNameToResourcePath(Constants.ENUM_PACKAGE) + "/*.class";

        //spring工具类，可以获取指定路径下的全部类
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        try {
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources(pattern);
            //MetadataReader 的工厂类
            MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
            for (Resource resource : resources) {
                //用于读取类信息
                MetadataReader reader = readerFactory.getMetadataReader(resource);
                //扫描到的class
                String classname = reader.getClassMetadata().getClassName();
                Class<?> clazz = Class.forName(classname);
                //将注解中的类型值作为key，对应的类作为 value
                handlerMap.put(classname.replace(Constants.ENUM_PACKAGE, ""), getEnumList(clazz));
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return handlerMap;
    }

}
